package battleship.view.fieldpainters;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JProgressBar;

import battleship.Controller;
import battleship.Loop;
import battleship.PluginEnd;
import battleship.Setup;
import battleship.boat.Boat;
import battleship.loop.MoveCollisionException;
import battleship.loop.OutOfSpaceException;
import battleship.player.Player;
import battleship.view.FieldPainter;

@SuppressWarnings("serial")
public class FieldPainterLoop extends FieldPainter{

	private Point currentPointClicked = null;
	private Image reticule;
	
	private FieldPainterLoop otherField;
	private JProgressBar progress;
	private JLabel hits;

	public FieldPainterLoop(
			Player owner,
			JLabel notificationArea,
			JProgressBar progress,
			JLabel hits)
	{
		super(owner, notificationArea);
		reticule = (new ImageIcon("images/reticule.png")).getImage();
		this.progress = progress;
		this.hits = hits;
		
		progress.setStringPainted(true);
		
		this.setHideShips(true);
	}
	
	public void setOtherField(FieldPainterLoop otherField)
	{
		this.otherField = otherField;
	}
	
	public JLabel getHitsLabel()
	{
		return hits;
	}

	@Override
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);

		Graphics2D g2 = (Graphics2D) g;
		
		if(Setup.getPlayer2(getFieldOwner()).isBot() && getEnabled())
		{
			boolean hit = Setup.getPlayer2(getFieldOwner()).getAI().attack(Setup.getPlayer2(getFieldOwner()));
			checkHit(hit, Setup.getPlayer2(getFieldOwner()).getAI().getX(),
					Setup.getPlayer2(getFieldOwner()).getAI().getY());
			switchFields();

			Loop.increaseTurns();
		}

		else {
			if (getEnabled())
			{


				int highlightX = (int) getLastPointHighlighted().getX() * 25;
				int highlightY = (int) getLastPointHighlighted().getY() * 25;


				g2.drawImage(reticule, highlightX, highlightY, this);
				g2.drawRect(highlightX, highlightY, 25, 25);

				setNotificationText(
						"Positie: " + Setup.getPositionMap()[highlightX/25] + "" + ((highlightY/25) + 1) ,
						false);
			}

			if ((getLastPointClicked() != currentPointClicked) && getEnabled())
			{


				int x = (int) getLastPointClicked().getX();
				int y = (int) getLastPointClicked().getY();
				currentPointClicked = getLastPointClicked();
				boolean hit;



				try {
					hit = Setup.getPlayer2(getFieldOwner()).strike(y, x);

					checkHit(hit, x, y);
					switchFields();

					Loop.increaseTurns();
					//setEnabled(false);
				} catch (MoveCollisionException e) {
					setNotificationText("Hier is al gevuurd", true);
				} catch (OutOfSpaceException e) {
					setNotificationText("Deze positie is buiten het veld", true);
					// there shouldn't be any possibility to select a position outside of the field.
				}
				repaint();	
			}
		}
		otherField.repaint();
	}
	
	public void checkHit(boolean hit, int x, int y)
	{
		if (hit)
		{
			Boat hitBoat = getFieldOwner().getField().getBoatAt(new int[] {y,x});
			if(hitBoat.getSunk())
			{
				if(Loop.getWin(Setup.getPlayer2(getFieldOwner()))) //check if this player won
				{
					setEnabled(false);
					otherField.setEnabled(false);
					
					setNotificationText(
							otherField.getFieldOwner().getName()
							+ " heeft gewonnen!",
							true);
					otherField.setNotificationText(
							getFieldOwner().getName()
							+ " heeft verloren!", 
							true);
					
					this.setEnabled(false);
					otherField.setEnabled(false);
					Loop.setWin(true);
					
					for(PluginEnd plugin : Controller.getPluginsEnd())
					{
						plugin.onEnd();
					}
				}
				else
				{
					setNotificationText(hitBoat.getName() + " gezonken", true);
				}
			}
			else
			{
				setNotificationText("U heeft de vijand geraakt!", true);
			}		
			updateHits();
			
			updateProgressBar();
		}
		else
		{
			setNotificationText("U heeft de vijand gemist!", true);
		}
	}
	
	public void updateProgressBar()
	{
		double totalLength = 0;
		
		double currentHits = Double.valueOf(hits.getText());
		
		for(int boat = 0; boat < getFieldOwner().getField().getBoats().length; boat++)
		{
			totalLength += getFieldOwner().getField().getBoats()[boat].getLength();
		}
		
		if(progress.getValue() < ((currentHits/totalLength) * 100))
		{
			progress.setValue((int) ((currentHits/totalLength) * 100));
			if(currentHits/totalLength == 1)
			{
				progress.setString("Spel gedaan!");
			}
			else
			{
				progress.setString("Winnen: " + Setup.getPlayer2(getFieldOwner()).getName());
			}
				
		}
	}
	
	public void updateHits()
	{
		int currentHits = 0;
		Boat[] boats = getFieldOwner().getField().getBoats();
		
		for(
				int boat = 0
				;boat < boats.length
				;++boat)
		{
			for (int boathit = 0; boathit < boats[boat].getHit().length; ++boathit)
			{
				if(boats[boat].getHit()[boathit]) currentHits++;
			}
		}
		
		hits.setText(Integer.toString(currentHits));
	}
	
	public void switchFields()
	{
		if(!Loop.getWin())
		{
			this.setEnabled(false);
			otherField.setEnabled(true);
		}
	}
}
